#include "Widget.h"
#include "ui_widget.h"
#include "customlistview.h"

#include "AddShortCutDialog.h"
#include "CmdUtil.h"
#include "CustomStyledItemDelegate.h"
#include "TwoColumnDelegate.h"
#include "csearchlineedit.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QStringListModel>
#include <QMessageBox>
#include <QStandardItem>
#include <QAction>
#include <QMenu>
#include <QSystemTrayIcon>
#include "CommandExecutor.h"
#include <QHotkey>
#include <QApplication>

#define FILTER_COL_NO 1

QString Widget::currentRowItem = "";
QStringList Widget::ShortCutCfgList;


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置窗口样式
    // this->setStyleSheet("background-color:#1A1E2");
    this->initUI();
    //连接信号与槽
    this->connectSignalsSlots();
    this->initExecCmd();

    this->initHotkey("Alt+p");

}
//https://blog.csdn.net/wj584652425/article/details/125124595



/**
 * 初始化UI界面
 * CSearchLineEdit 搜索框
 * CustomListView 列表
 * CustomTableView 表格
 * QLabel 状态栏
 * @brief Widget::initUI
 */
void Widget::initUI(){
    //创建编辑栏
    pEdit = new CSearchLineEdit(this);

    //创建垂直布局，并把编辑栏放进去，由于就一个部件，垂直或者水平都行
    pVLay = new QVBoxLayout(this);
    pVLay->addWidget(pEdit);
    // 通过调用setFocus()让lineEdit获得焦点
    pEdit->setFocus();

    // pVLay->addStretch(5);

    // listView = createListView();
    // listView = createListView2();
    // listView = createListView3();
    listView = createListView4();
    pVLay->addWidget(listView);
    // listView->setVisible(true);//false隐藏组件


    // pVLay->addStretch(2);
    label = new QLabel(this);
    QFont font ( "Microsoft YaHei", 12, 20); //第一个属性是字体（微软雅黑），第二个是大小，第三个是加粗（权重是75）
    label->setFont(font);
    label->setText("选中值:");
    // label->move(300,300);
    pVLay->addWidget(label);

    QString result = concatenateStrings("Hello, ", "World!");
    qDebug() << result; // 输出: "Hello, World!"
    //托盘
    this->sysTrayInit();

    // 构造函数中要给Widget设置风格 WS_OVERLAPPEDWINDOW
    // this->setWindowFlags(Qt::FramelessWindowHint);
}

void Widget::initUIListView(){
    // 创建一个 QStringListModel
    QStringListModel *model = new QStringListModel(this);
    QStringList list;
    list << "Item 1 | Value 11" << "Item 2 | Value 2" << "Item 3 | Value 3" << "Item 4 | Value 4";
    model->setStringList(list);

    // 创建一个 QListView
    CustomListView *listView = new CustomListView(this);
    listView->setModel(model);

    // 设置自定义委托
    TwoColumnDelegate *delegate = new TwoColumnDelegate(this);
    listView->setItemDelegate(delegate);
}


/**
 * 当ListView只剩一项时再按空格则运行这一项程序
 * @brief Widget::runOnlyOneItem
 */
void Widget::runOnlyOneItem()
{
    QModelIndex currentIndex = listView->currentIndex();
    QString itemText = listView->model()->data(currentIndex).toString();
    qDebug() <<"runOnlyOneItem-结果只剩一项:"<< itemText;
    listView ->runListRow(itemText);
    this->hide();
    this->pEdit->setText("");
}

void Widget::runOnlyOneItem(QString itemText)
{
    qDebug() <<"runOnlyOneItem-结果只剩一项:"<< itemText;
    listView ->runListRow(itemText);
    this->hide();
    this->pEdit->setText("");
}

/**
 * 调用connect连接信号与槽
 * @brief Widget::connectSignalsSlots
 */
void Widget::connectSignalsSlots()
{
    //搜索框中的收到信号时执行handleSearch方法(搜索按钮发送sig_Search信号)
    connect(pEdit, &CSearchLineEdit::sig_Search, this,  &Widget::handleSearch);//connect(pEdit, &CSearchLineEdit::sig_Search, pEdit, &CSearchLineEdit::handleSearch2);
    //搜索框文本变化时执行OnTextChanged
    connect(pEdit, &QLineEdit::textChanged, this, &Widget::OnTextChanged);//输入框变化时打印输入框的内容
    //搜索框中按Tab键时执行onTabPressed方法
    connect(pEdit, &CSearchLineEdit::tabPressed, this, &Widget::onTabPressed);

    //当widget发送itemMoved信号时调用CustomListView的槽函数以选中ListView的下一项
    //connect(this, SIGNAL(itemMoved(int)), listView, SLOT(itemMovedSlot(int)));
    connect(this,&Widget::itemMoved , listView, &CustomListView::itemMovedSlot);
    connect(this,&Widget::itemMovedPrev , listView, &CustomListView::itemMovedPrevSlot);

    connect(this, &Widget::itemMoved, this, [this](int value,const QString &key, const QString &text) {
        handleSearch(text);
    });
    //在CustomListView接收到sig_input信号时调用onListViewKeyPressed方法(设置搜索框为输入焦点,补全搜索框要搜索的字符,因为某一刻焦点不在搜索框时输入的字符)
    connect(listView,&CustomListView::sig_input , this, &Widget::onListViewKeyPressed);
    //检测编辑框中按下空格时
    QObject::connect(pEdit, &CSearchLineEdit::spacePressed, [this](){
        qDebug() << "捕获到spacePressed信号->空格键被按下"<<pEdit->text();
        int count = listView->model()->rowCount();
        qDebug() <<"listView.count=="<< count;
        if(count == 1){
            runOnlyOneItem();
        }

    });
}


Widget::~Widget()
{
    delete ui;
}

/**
 * 给QLabel设置文本
 * @brief Widget::handleSearch
 * @param text
 */
void Widget::handleSearch(const QString &text)
{
    qDebug()<<"槽函数handleSearch收到的信号,设置状态栏:"<<text;
    label->setText(text);
}

void Widget::handleSearch2(int value,const QString &key ,const QString &text)
{
    qDebug()<<"槽函数handleSearch2收到的信号,设置状态栏:"<<text;
    // label->setText(pEdit->text());
    label->setText(key);
}

/**
 *
 * 搜索框内容变化时获取输入的字符串,并调用过滤方法更新CustomTableView
 * @brief Widget::OnTextChanged
 * @param text
 */
void Widget::OnTextChanged(const QString& text)
{
    qDebug()<<"widget.cpp:文本框目前的内容是="<<text;
    if(text.startsWith(" ") == 1){
        pEdit->clear();
        return;
    }
    listView -> selectFirstRow();
    //TableView过滤搜索框中的字符串
    // this-> tableView->filterData(proxyModel,itemModel,text);

    //当搜索框内容变化时检查QTableView中的过滤结果是否只有一条记录
    // this->tableView->selectFirstRow3();

    //ListView过滤搜索框中的字符串
    //this->listView->filterDataSlot(text);

    this->recordSelectedRowItem();//记录选择的非空的项
    //当搜索框内容变化时检查QListView中的过滤结果是否只有一条记录
    int rc = this->listView->model()->rowCount();
    if(rc == 0){
        this->runOnlyOneItem(Widget::currentRowItem);
    }
}

void Widget::recordSelectedRowItem(){
    QString selectedRow = listView->getSelectedRowItem() ;
    if(!selectedRow.isEmpty()){
        currentRowItem = selectedRow;
    }
}

/**
 * @brief Widget::onTabPressed
 */
void Widget::onTabPressed() // 槽函数，用于处理Tab键按下的事件
{
    // 在这里实现你需要的功能，例如弹出提示框等
    qDebug()<<"widget->onTabPressed:在这里实现你需要的功能，例如弹出提示框等=";
}

/**
 * 在Widget界面中响应键盘按键
 * 1. 按Tab时发送信号itemMoved,收到该信号的QListView或QTableView向下移动一项
 * @brief Widget::keyPressEvent
 * @param event
 */
void Widget::keyPressEvent(QKeyEvent *event)
{
    // if (event->key() == Qt::Key_Tab) {
    //     emit tabPressed(); // 发送一个自定义信号，用于触发其他槽函数
    // } else {
    //     QWidget::keyPressEvent(event); // 正常处理按键事件
    // }
    pEdit->setFocus();
    QDateTime currentTime = QDateTime::currentDateTime();
    QString currTime = currentTime.toString("yyyy-MM-dd hh:mm:ss");
    QString selectedRow = "选择的值";
    if (event->key()==Qt::Key_Tab){
        qDebug()<<"widget.cpp按了Tab键,准备发送itemMoved信号";
        emit itemMoved(1001,selectedRow, "信号内容:我来自Widget中的keyPressEvent-Tab键("+currTime+")");
        this->label->setText("命令= " +listView->getSelectedRowText());
        this->recordSelectedRowItem();//记录选择的非空的项
    }else if (event->key() == Qt::Key_Backtab) {
        // qDebug()<<"widget.cpp:你按了Shift+Tab键";
        emit itemMovedPrev(1002,selectedRow, "信号内容:我来自Widget中的keyPressEvent,你按了Shift+Tab键("+currTime+")");
        this->label->setText("命令=" + listView->getSelectedRowText());
        this->recordSelectedRowItem();//记录选择的非空的项
    }else if (event->key()==Qt::Key_Escape){
        qDebug()<<"widget.cpp:你按了ESC键";
        this->close();
    }else if(event->key() == Qt::Key_Space){
        //在编辑框中按空格则显示ListView选中的项
        QModelIndex currentIndex = listView->currentIndex();
        QString itemText = listView->model()->data(currentIndex).toString();

        // 显示选中项的信息
        qDebug() <<"Widget中按空格键-此时ListView选中的项"<< itemText;
        // QMessageBox::warning(this, "Widget::keyPressEvent选中的项", "当前选中了项: " + itemText);
        // this->onSelectedRow();

        runOnlyOneItem();
    }
    event->accept(); //被处理,不会再传播到父窗体
}




void Widget::onListViewKeyPressed(QString *text){
    qDebug()<<"listView要过滤的字符串"<<text->toStdString().c_str();
    pEdit->setFocus();
    pEdit->setText(pEdit->text().append(text));
    listView -> selectFirstRow();
}



QStringList Widget::readShortCutList(QString iniFilePath){
    QFile file(iniFilePath);
    QStringList listResult;
    if (file.open(QFile::ReadWrite)) {
        QTextStream stream(&file);

        QString line;// = stream.readLine();
        // QStringList list = line.simplified().split('|');
        int row = 0;
        QString newItem = nullptr;
        while (!stream.atEnd()) {
            line = stream.readLine();
            if (!line.startsWith('#') && line.contains('|')) {
                // list = line.simplified().split('|');
                listResult.append( line);//.simplified());
            }
        }

    }
    file.close();
    return listResult;
}

void Widget::initHotkey(const QString hotkeyStr)
{
    QHotkey *hotkey = new QHotkey(QKeySequence(hotkeyStr), true); // Alt 和 P 之间不能有空格
    qDebug() << "Is Registered: " << hotkey->isRegistered();

    connect(hotkey, &QHotkey::activated, [this](){


        qDebug() << "Hotkey Activated - the application will quit now";
        // 假设你有一个QWidget指针叫做 myWidget
        if (this->isHidden()) {
            // 窗口是隐藏的
            qDebug() << "Window is hidden,准备让它显示到最前面";
            pEdit->setText("");
            this->show();
            this->raise();
            this->activateWindow();
            this->raise();
            QApplication::setActiveWindow(this);
            this->raise();
        } else {
            // 窗口是显示的
            qDebug() << "Window is show,准备让它隐藏";
            this->hide();
            this->isActiveWindow();
        }
    });
}

CustomListView* Widget::createListView4(){
    listShowModel = new QStringListModel(this) ;
    // ShortCutCfgList << "F101 |Computer1 |我的电脑3     |::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
    //              << "F0   |Explorer        |资源管理器   |explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
    //              << "F1   |MyDocument      |我的文档     |explorer.exe"
    //              << "F9   |notepad         |记事本     |notepad.exe";
    // initTextList = readShortCutList("D:\\GreenTool\\A-AutoRun\\ALTRun\\ShortCutList.txt");
    ShortCutCfgList = readShortCutList("D:\\dtemp\\ShortCutList.txt");
    listShowModel -> setStringList(ShortCutCfgList);
    listView = new CustomListView(this);

    // connect(pEdit, &QLineEdit::textChanged, listView, &CustomListView::filterDataSlot);
    connect(pEdit, &QLineEdit::textChanged, [this](const QString &text) {
        // 假设 ShortCutCfgList 是一个预定义的 QStringList
        listView->filterDataSlot(ShortCutCfgList, text);//这里ShortCutCfgList必须是成员变量,否则提示:error: Use of undeclared identifier 'items'
    });


    // 解析并排序数据
    QList<QPair<int, QString>> sortedData = listView->parseAndSortData(ShortCutCfgList);
    // 添加序号列
    QStringList indexedData = listView->addIndexColumn(sortedData);

    // 设置初始数据
    // listView->setData(ShortCutCfgList);
    listView->setData(indexedData);
    // listView->setModel(listShowModel);
    // 设置自定义委托
    TwoColumnDelegate *delegate = new TwoColumnDelegate(this);
    // CustomStyledItemDelegate *delegate = new CustomStyledItemDelegate(this);
    listView->setItemDelegate(delegate);
    return listView;
}




void Widget::afterProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << "exitCode=" << exitCode;
    qDebug() << "exitStatus=" << exitStatus  ;

    proc->close();
    delete proc;
    proc = nullptr;
}

void Widget::rightMessage()
{
    QByteArray strdata = proc->readAllStandardOutput();
    QString strDataLocal = QString::fromLocal8Bit(strdata);
    qDebug() << "rightMessage=" << (strDataLocal);

}

void Widget::wrongMessage()
{
    QByteArray strdata = proc->readAllStandardError();
    // ui->txtReport->setTextColor(Qt::red);
    QString strDataLocal = QString::fromLocal8Bit(strdata);
    // ui->txtReport->append(strDataLocal);
    qDebug() << "rightMessage=" << (strDataLocal);
}

void Widget::afterProcStarted()
{
    qDebug() << "afterProcStarted=" << "程序已启动....准备关闭窗口";
}
void Widget::initExecCmd(){
    proc = new QProcess();

    executor = new CommandExecutor;

    /* show output */
    connect(proc, &QProcess::readyReadStandardOutput, this, &Widget::rightMessage);
    connect(proc, &QProcess::readyReadStandardError, this, &Widget::wrongMessage);

    connect(proc, &QProcess::started, this, &Widget::afterProcStarted);
    connect(proc,static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),this,&Widget::afterProcFinished);
}


//https://blog.csdn.net/qq_33154343/article/details/124639169
void Widget::sysTrayInit()
{
    QAction *show_action = new QAction("显示主窗口");
    QAction *min_action = new QAction("最小化");
    QAction *quit_action = new QAction("退出");
    QMenu *tray_menu = new QMenu;
    tray_menu->addAction(show_action);
    tray_menu->addAction(min_action);
    tray_menu->addSeparator();
    tray_menu->addAction(quit_action);

    connect(show_action,&QAction::triggered,this,[=](){ this->showNormal(); });
    connect(min_action,&QAction::triggered,this,[=](){ this->showMinimized(); });
    connect(quit_action,&QAction::triggered,this,[=](){ close();    /*QApplication::quit();*/ });  //close() 关闭时会触发关闭事件  可以根据需求修改

    m_systray = new QSystemTrayIcon(this);
    // m_systray->setIcon(QIcon(":/resources/Synced.svg"));   //必须要给一个Icon
    m_systray->setIcon(QIcon(":/resources/AppIcon.png"));   //必须要给一个Icon
    m_systray->setToolTip("我是最小化托盘按钮");
    m_systray->setContextMenu(tray_menu);   //设置右键菜单

    connect(m_systray,&QSystemTrayIcon::activated,this,&Widget::SysTrayActivated);
    m_systray->show();
}

void Widget::SysTrayActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason)
    {
    case QSystemTrayIcon::Trigger :
    case QSystemTrayIcon::DoubleClick :
        qDebug()<<"双击";
        m_systray->showMessage("title","被双击");
        this->showNormal();
        break;

    case QSystemTrayIcon::MiddleClick :
        m_systray->showMessage("title","被中击");
        qDebug()<<"中击";
        break;

    default:
        qDebug()<<"No work";
        break;
    }
}
// 函数用于判断给定路径的文件类型
QString getFileType(const QString &path) {
    QFileInfo fileInfo(path);
    if (fileInfo.isFile()) {
        return "文件";
    } else if (fileInfo.isDir()) {
        return "目录";
    } else {
        return "其他";
    }
}
void Widget::handleFile(const QString &filePath){
    // 在这里处理文件路径
    AddShortCutDialog  *scDlg = new AddShortCutDialog;
    QString name = CmdUtil::getSystemUserName();
    // QMessageBox::information(this, "File Received"+name, "Received file: " + filePath);
    QFileInfo fileInfo(filePath);
    if (fileInfo.isFile()) {
        QString filesuffix = fileInfo.suffix();
        QString fileName = fileInfo.fileName();


    } else if (fileInfo.isDir()) {
        // return "目录";
    } else {
        // return "其他";
    }

    scDlg->show();
}
